package com.k8.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ClassUtil {
    private static String mid_fix = ",";
    private static String pre_fix = "(";
    private static String last_fix = ")";
    private static String java_package_prefix = "java";

    public static String getMethodToString(Method method) {
        StringBuilder stringBuilder = new StringBuilder();
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        stringBuilder.append(methodName).append(pre_fix);
        for (Class<?> parameterType : parameterTypes) {
            String fullName = parameterType.getName();
            if (fullName.indexOf(java_package_prefix) == 0) fullName = parameterType.getSimpleName();
            stringBuilder.append(fullName).append(mid_fix);
        }
        if (parameterTypes.length > 0) {
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
        stringBuilder.append(last_fix);
        return stringBuilder.toString();
    }

    public static String getMethodToString(String methodName, Class<?>[] parameterTypes) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(methodName).append(pre_fix);
        for (Class<?> parameterType : parameterTypes) {
            String fullName = parameterType.getName();
            if (fullName.indexOf(java_package_prefix) == 0) fullName = parameterType.getSimpleName();
            stringBuilder.append(fullName).append(mid_fix);
        }
        if (parameterTypes.length > 0) {
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
        stringBuilder.append(last_fix);
        return stringBuilder.toString();
    }

    public static Method getSetter(Class clazz, Field field) throws NoSuchMethodException {
        String fieldName = field.getName();
        String setterName = "set" + fieldName.replaceFirst(fieldName.substring(0, 1), fieldName.substring(0, 1).toUpperCase());
        return clazz.getMethod(setterName, field.getType());
    }

    public static Method getGetter(Class clazz, Field field) throws NoSuchMethodException {
        String fieldName = field.getName();
        String getterName = "get" + fieldName.replaceFirst(fieldName.substring(0, 1), fieldName.substring(0, 1).toUpperCase());
        return clazz.getMethod(getterName);
    }

    public static String simpleClassName(Class<?> clazz) {
        if (clazz == null) {
            throw new NullPointerException("clazz");
        }
        String className = clazz.getName();
        final int lastDotIdx = className.lastIndexOf(".");
        if (lastDotIdx > -1) {
            return className.substring(lastDotIdx + 1);
        }
        return className;
    }

    public static ClassLoader getClassLoader(Class<?> clazz) {
        ClassLoader cl = null;
        if (!clazz.getName().startsWith("com.k8")) {
            cl = clazz.getClassLoader();
        }
        if (cl == null) {
            try {
                cl = Thread.currentThread().getContextClassLoader();
            } catch (Exception ignored) {
                // Cannot access thread context ClassLoader - falling back to system class loader...
            }
            if (cl == null) {
                // No thread context class loader -> use class loader of this class.
                cl = clazz.getClassLoader();
                if (cl == null) {
                    // getClassLoader() returning null indicates the bootstrap ClassLoader
                    try {
                        cl = ClassLoader.getSystemClassLoader();
                    } catch (Exception ignored) {
                        // Cannot access system ClassLoader - oh well, maybe the caller can live with null...
                    }
                }
            }
        }

        return cl;
    }

}
